/*
 * socket related helpers
 *
 * $Id: sock.c 29 2009-05-05 16:31:09Z ybc2084 $
 */

#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "sock.h"

/*
 * return a socket connect to 'ipaddr:port', if failed, return -1.
 *
 * Note: 'port' is int type, since if it is signed short,
 * it may not be able to represent 65536 (assume signed
 * short is 16-bit on the lower level machine).
 */
int connTo(const char *ipaddr, int port)
{
	int		sock;
	int		rc = 0;
	struct sockaddr_in	svrend;

	if (!ipaddr || port <= 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	/* specify server end point addr:port */
	svrend.sin_family	= AF_INET;
	svrend.sin_port		= htons(port);
	rc = inet_aton(ipaddr, &svrend.sin_addr);
	if (!rc) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	/*
	 * XXX: need to consider INTERRUPT by signal
	 */
	rc = connect(sock, (struct sockaddr *)&svrend, sizeof(struct sockaddr_in));
	if (rc < 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	return (sock);
}

/*
 * return a socket listen on 'ipaddr:port', if failed, return -1.
 *
 * Note: 'port' is int type, since if it is signed short,
 * it may not be able to represent 65536 (assume signed
 * short is 16-bit on the lower level machine).
 */
int listenOn(const char *ipaddr, int port)
{
	int	                rc = 0;
	int	                sock;
	struct sockaddr_in  svrend;

	if (!ipaddr || port <= 0 || port > (int)0xFFFF) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	/* specify server end point addr:port */
	svrend.sin_family = AF_INET;
	svrend.sin_port	  = htons(port);
	rc = inet_aton(ipaddr, &svrend.sin_addr);
	if (!rc) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	/*
	 * XXX: may need to consider INTERRUPT by signal
	 */
	rc = bind(sock, (struct sockaddr *)&svrend, sizeof(struct sockaddr_in));
	if (rc < 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

    rc = listen(sock, SOMAXCONN);
    if (rc < 0) {
		/*
		 * XXX: log
		 */
		return (-1);
	}

	return (sock);
}

